import { IBoxLayoutElement } from "./IElement.js";
import { IText, ITextCharacter } from "./IText.js";
import { IEventChange } from "./IEvent.js";

export class ISelectOption extends IText {
    constructor() {
        super();
        this.SetTagName("ISelectOption");
        this.SetPaddingLeft(this.GetLineHeight() * this.GetFontSize());
        this.SetBackgroundColor(this.GetThemeBackgroundColor());
        this.SetBorderBottomWidth(this.GetThemeBorderWidth());
        this.SetBorderBottomColor(this.GetThemeBorderColor());
        this.SetSupportHover(true);

        this.SetAttributeSetterGetter("label", (value) => { this.SetText(value); })
        this.SetAttributeSetterGetter("value", (value) => { this.SetValue(value); });
    }

    SetSelect(select) { this.m_select = select; }
    GetSelect() { return this.m_select; }
    SetValue(value) { this.m_value = value; }
    GetValue() { return this.m_value; }

    OnClick(event) {
        this.GetSelect().SetSelectedOption(this);
    }
}

export class ISelectOptionGroup extends IBoxLayoutElement {
    constructor() {
        super();
        this.SetTagName("ISelectOptionGroup");
        this.SetBorder(this.GetThemeBorderWidth(), this.GetThemeBorderStyle(), this.GetThemeBorderColor());
        this.SetPadding(this.GetThemePaddingTopBottom(), this.GetThemePaddingLeftRight());
        this.SetBackgroundColor(this.GetThemeBackgroundColor());
        this.SetModal(true);
    }

    SetSelect(select) { this.m_select = select; }
    GetSelect() { return this.m_select; }

    UpdateLayout() {
        const select = this.GetSelect();
        const select_x = select.GetX();
        const select_y = select.GetY();
        const select_width = select.GetWidth();
        const select_height = select.GetHeight();
        this.SetLocalWidth(select_width)
        super.UpdateLayout();
        const content_width = this.GetLocalContentWidth() + this.GetPaddingBorderWidth();
        const local_width = Math.min(Math.max(select_width, content_width), select.GetMaxOptionWidth());
        if (select_width !== local_width) {
            this.SetLocalWidth(local_width);
            const childrens = this.GetChildrens();
            for (let i = 0; i < childrens.length; i++) {
                const children = childrens[i];
                children.SetLocalWidth(local_width);
            }
        }
        this.SetLocalX(select_x + (select_width - local_width) / 2);
        this.SetLocalY(select_y + select_height + 2);
    }

    UpdatePosition() {
        super.UpdatePosition();
        const select = this.GetSelect();
        const select_value = select.GetValue();
        const select_option_icon = select.GetSelectOptionIcon();
        const childrens = this.GetChildrens();
        for (let i = 0; i < childrens.length; i++) {
            const children = childrens[i];
            if (children instanceof ISelectOption && children.GetValue() === select_value) {
                const selected_option = children;
                select_option_icon.SetParent(selected_option);
                select_option_icon.SetPositionAncestor(selected_option);
                select_option_icon.SetRoot(selected_option.GetRoot());
                select_option_icon.SetWindow(selected_option.GetWindow());
                select_option_icon.SetFontColor(selected_option.GetFontColor());
                select_option_icon.SetFontSize(selected_option.GetFontSize());
                select_option_icon.SetLineHeight(selected_option.GetLineHeight());
                select_option_icon.SetLeft(selected_option.GetBorderLeftWidth());
                select_option_icon.SetTop(selected_option.GetTopPaddingBorderSize());
                select_option_icon.SetStyleWidth(selected_option.GetMaxContentHeight());
                select_option_icon.SetStyleHeight(selected_option.GetMaxContentHeight());
                select_option_icon.UpdateLayout();
                select_option_icon.UpdatePosition();
            }
        }
    }

    OnClickBubble(event) {
        this.Close();
    }

    Show() {
        const select = this.GetSelect();
        this.SetRoot(select.GetRoot());
        this.SetWindow(select.GetWindow());
        this.SetVisible(true);
        this.SetFixedPosition(true);
        this.GetRoot().InsertChildren(this);
    }

    Close() {
        this.Refresh();
        this.GetRoot().DeleteChildren(this);
        this.SetVisible(false);
    }
}

export class ISelect extends IText {
    constructor() {
        super();
        this.SetTagName("ISelect");
        this.SetPadding(this.GetThemePaddingTopBottom(), this.GetThemePaddingLeftRight());
        this.SetBorder(this.GetThemeBorderWidth(), this.GetThemeBorderStyle(), this.GetThemeBorderColor());
        this.SetStyleWidth(this.GetThemeInlineWidth());
        this.SetStyleHeight(this.GetThemeInlineHeight());

        this.m_select_option_icon = new ITextCharacter(true);
        this.m_select_option_icon.SetFontFamily("iconfont");
        this.m_select_option_icon.SetValue("icon-circle");
        this.m_select_option_icon.SetFixedPosition(true);
        this.m_select_option_group = new ISelectOptionGroup();
        this.m_select_option_group.SetVisible(false);
        this.m_select_option_group.SetSelect(this);
        this.SetAttributeSetterGetter("value", (value) => { this.SetValue(value); });
    }

    GetSelectOptionIcon() { return this.m_select_option_icon; }
    GetSelectOptionGroup() { return this.m_select_option_group; }
    GetMaxOptionWidth() { return 200; }
    GetValue() { return this.m_value; }

    SetValue(value) {
        this.m_value = value;
        const select_option_group = this.GetSelectOptionGroup();
        const childrens = select_option_group.GetChildrens();
        for (let i = 0; i < childrens.length; i++) {
            const children = childrens[i];
            if (children instanceof ISelectOption) {
                if (children.GetValue() === value) {
                    this.SetText(children.GetText());
                    break;
                }
            }
        }
    }

    SetSelectedOption(option) {
        this.m_value = option.GetValue();
        this.SetText(option.GetText());
        this.OnChange();
    }

    UpdateChildren() {
        const select_option_group = this.GetSelectOptionGroup();
        select_option_group.ClearChildren();
        const childrens = this.GetChildrens();
        for (let i = 0; i < childrens.length; i++) {
            const children = childrens[i];
            if (children instanceof ISelectOption) {
                children.SetSelect(this);
                select_option_group.InsertChildren(children);
            }
        }
        this.ClearChildren();
        this.SetChildrenChanged(false);
        this.SetValue(this.GetValue());
    }

    OnClick(event) {
        this.ShowOptions();
    }

    ShowOptions() {
        const select_option_group = this.GetSelectOptionGroup();
        if (select_option_group.IsVisible() || select_option_group.GetChildrens().length === 0) return;
        select_option_group.Show();
    }

    CloseOptions() {
        const select_option_group = this.GetSelectOptionGroup();
        if (!select_option_group.IsVisible()) return;
        select_option_group.Close();
    }

    OnChange() {
        const event = new IEventChange();
        event.SetValue(this.GetValue());
        this.DispatchEvent(event);
    }

    set value(value) {
        this.SetValue(value);
    }
}


export class SelectOption extends ISelectOption {
    constructor() {
        super();
        this.SetTagName("SelectOption");
    }
}

export class Select extends ISelect {
    constructor() {
        super();
        this.SetTagName("Select");
    }
}